
const CryptoJS = require('../aliyun/CryptoJS/crypto-js.js');
const uuid = require('../aliyun/uuid/index.js');

const form = 'application/x-www-form-urlencoded';
const hasOwnProperty = function (obj, key) {
  return Object.prototype.hasOwnProperty.call(obj, key);
};

function parseURL(url) {
  // var index = obj.lastIndexOf("\-");
  // obj = obj.substring(index + 1, obj.length);
  // return obj;

  var path = url.split('com')
  return path[1];
}

function aliyun_api_gateway(key, secret, stage = 'RELEASE') {
  this.appKey = key;
// this.appSecret = Buffer.from(secret, 'utf8');
  this.appSecret = secret;
  this.stage = stage;

}

aliyun_api_gateway.prototype.InitParams = function (method, id, version, url, apiVer, params, iotToken) {
  this.method = method;
  this.id = id;
  this.version = version;
  this.url = url;
  this.apiVer = apiVer;
  this.params = params;
  this.iotToken = iotToken;
}

aliyun_api_gateway.prototype.buildStringToSign = function (method, headers, signedHeadersStr, parsedUrl, data) {
  // accept, contentMD5, contentType,
  const lf = '\n';
  var list = [method, lf];

  var accept = headers['accept'];
  if (accept) {
    list.push(accept);
  }
  list.push(lf);

  var contentMD5 = headers['content-md5'];
  if (contentMD5) {
    list.push(contentMD5);
  }
  list.push(lf);

  var contentType = headers['content-type'] || '';
  if (contentType) {
    list.push(contentType);
  }
  list.push(lf);

  var date = headers['date'];
  if (date) {
    list.push(date);
  }
  list.push(lf);

  if (signedHeadersStr) {
    list.push(signedHeadersStr);
    list.push(lf);
  }

  list.push(parsedUrl);
  /*
  if (contentType.startsWith(form)) {
    list.push(this.buildUrl(url, data));
  } else {
    list.push(this.buildUrl(url));
  }*/

  return list.join('');
}

aliyun_api_gateway.prototype.sign = function (stringToSign) {
  return crypto.createHmac('sha256', this.appSecret)
    .update(stringToSign, 'utf8').digest('base64');
}

aliyun_api_gateway.prototype.md5 = function (content) {
  return crypto.createHash('md5')
    .update(content, 'utf8')
    .digest('base64');
}

aliyun_api_gateway.prototype.getSignHeaderKeys = function (headers, signHeaders) {
  var keys = Object.keys(headers).sort();
  var signKeys = [];
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    // x-ca- 开头的header或者指定的header
    if (key.startsWith('x-ca-') || hasOwnProperty(signHeaders, key)) {
      signKeys.push(key);
    }
  }

  // 按字典序排序
  return signKeys.sort();
}

aliyun_api_gateway.prototype.buildUrl = function (parsedUrl, data) {
  var toStringify = Object.assign(parsedUrl.query, data);
  var result = parsedUrl.pathname;
  if (Object.keys(toStringify).length) {
    var keys = Object.keys(toStringify).sort();
    var list = new Array(keys.length);
    for (var i = 0; i < keys.length; i++) {
      var key = keys[i];
      if (toStringify[key] !== undefined && toStringify[key] !== null && ('' + toStringify[key])) {
        list[i] = `${key}=${toStringify[key]}`;
      } else {
        list[i] = `${key}`;
      }
    }
    result += '?' + list.join('&');
  }
  return result;
}

aliyun_api_gateway.prototype.buildHeaders = function (headers = {}, signHeaders) {
  return Object.assign({
    'x-ca-timestamp': Date.now(),
    'x-ca-key': this.appKey,
    'x-ca-nonce': uuid.v4(),
    'x-ca-stage': this.stage,
    'accept': 'application/json'
  }, headers, signHeaders);
}

aliyun_api_gateway.prototype.getSignedHeadersString = function (signHeaders, headers) {
  var list = [];
  for (var i = 0; i < signHeaders.length; i++) {
    var key = signHeaders[i];
    list.push(key + ':' + headers[key]);
  }

  return list.join('\n');
}

aliyun_api_gateway.prototype.preCreateHeaders = function () {
  var data = {
    "id": this.id,
    "version": this.version,
    "request": {
      "apiVer": this.apiVer
    },
    "params": this.params
  }
  this.opts = {
    data: data,
    headers: {
      accept: 'application/json',
      'content-type': 'application/json'
    },
    timeout: 3000,
    signHeaders: {}
  }
  this.originData = {
    id: this.id,
    version: this.version,
    request: {
      iotToken: this.iotToken,
      apiVer: this.apiVer
    },
    params: {
      request: {
        accountMetaV2: [Object]
      }
    }
  }
}

aliyun_api_gateway.prototype.createStruct = function () {
  this.preCreateHeaders()
  
  var method = this.method;
  var url = this.url;
  var opts = this.opts;
  var originData = this.originData;

  var signHeaders = opts.signHeaders;
  // 小写化，合并之后的headers
  var headers = this.buildHeaders(opts.headers, signHeaders);

/*
  opts.data = {
    "id": "030887d0-550c-11e9-991c-d3645309abcb",
    "version": "1.0",
    "request": {
      "apiVer": "1.0.5"
    },
    "params": {
      "request": {
        "accountMetaV2": {
          "phone": "17751513863",
          "password": "qwer123456",
          "appKey": "25812429"
        }
      }
    }
  }
*/
  var requestContentType = headers['content-type'] || '';
  if (method === 'POST' && !requestContentType.startsWith(form)) {
    // MD5 HASH
    var jsonStr = JSON.stringify(opts.data);
    var md5 = CryptoJS.MD5(jsonStr);
    headers['content-md5'] = CryptoJS.enc.Base64.stringify(md5);
  }

  
  var signHeaderKeys = this.getSignHeaderKeys(headers, signHeaders);
  headers['x-ca-signature-headers'] = signHeaderKeys.join(',');
  var signedHeadersStr = this.getSignedHeadersString(signHeaderKeys, headers);

  
  
  var parsedUrl = parseURL(url);
//  var parsedUrl = parse(url, true);
  var stringToSign = this.buildStringToSign(method, headers, signedHeadersStr, parsedUrl, originData);
//  headers['x-ca-signature'] = this.sign(stringToSign);
  // MD5 HASH
  var hmacSHA256 = CryptoJS.HmacSHA256(stringToSign, this.appSecret);
//  hmacSHA256 = 
  headers['x-ca-signature'] = CryptoJS.enc.Base64.stringify(hmacSHA256);

  // console.log('----------------------stringToSign-----------------------')
  // console.log(stringToSign)
  // console.log('--------------------x-ca-signature---------------------')
  // console.log(headers['x-ca-signature'])

  return {
    headers: headers,
    data: opts.data,
  };
}

function request(params, method = 'POST') {
   var api = new aliyun_api_gateway('25812429', '51cc0336d6419c3f9ce6976d6f542473')
//  var api = new aliyun_api_gateway('25389605', 'b7f3d31a1c6d7340d4c67d6c9953e314')
  api.InitParams(method, uuid.v1(), '1.0', params.url, params.apiVer, params.param)
  var obj = api.createStruct()
  var run = new Promise(function (resolve, reject) {
    wx.request({
      url: params.url,
      method: method,
      data: obj.data,
      header: obj.headers,
      success(res) {
        if (res.data.code === 200) {
          resolve(res.data)
        } else {
          reject(res)
        }
      },
      fail(res) {
        console.log(res)
        reject(res)
      }
    })
  })

  return run
}

module.exports = {
  request: request,
  aliyun_api_gateway: aliyun_api_gateway,
  uuid: uuid
}